package com.atxiaodei.nio.nioday01;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * @author wangmeng
 * @date 2020/9/19
 * jdk1.8中新增了 LocalDate 与 LocalDateTime等类来解决日期处理方法，同时引入了一个新的类
 * DateTimeFormatter 来解决日期格式化问题。可以使用Instant代替 Date，LocalDateTime代替
 * Calendar，DateTimeFormatter 代替 SimpleDateFormat。
 * 和 SimpleDateFormat 相比，DateTimeFormatter 是线程安全的。
 * Instant 的精确度更高，可以精确到纳秒级。
 * Duration 可以便捷得到时间段内的天数、小时数等。
 * LocalDateTime 能够快速地获取年、月、日、下一月等。
 * TemporalAdjusters 类中包含许多常用的静态方法，避免自己编写工具类。
 **/
public class Jdk8newDate {


    /**
     * Clock
     * Clock 类提供了访问当前日期和时间的方法，Clock 是时区敏感的，可以用来取代
     * System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用 Instant 类
     * 来表示， Instant 类也可以用来创建旧版本的 java.util.Date 对象。
     */
    @Test
    public void test(){
        Clock clock = Clock.systemDefaultZone();
        long millis = clock.millis();
        System.out.println(millis);// 输出1600446845877
       /* try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/
        long millis1 = clock.millis();
        System.out.println(millis1);// 输出1600446845877
        long end=millis1-millis;
        System.out.println(end);
        Instant instant = clock.instant();
        System.out.println(instant);// 输出2020-09-18T16:34:05.877Z
        Date from = Date.from(instant);
        System.out.println(from);// 输出Sat Sep 19 00:35:23 CST 2020
    }

    /**
     * LocalTime(本地时间)
     * LocalTime 定义了一个没有时区信息的时间，例如 晚上10点或者 17:30:15。下面的例子使用前面代码
     * 创建的时区创建了两个本地时间。之后比较时间并以小时和分钟为单位计算两个时间的时间差：
     */
    @Test
    public void test1(){
        //输出所有区域标识符
        System.out.println(ZoneId.getAvailableZoneIds());
        ZoneId zone1 = ZoneId.of("Europe/Berlin");
        ZoneId zone2 = ZoneId.of("Brazil/East");
        System.out.println(zone1.getRules());// ZoneRules[currentStandardOffset=+01:00]
        System.out.println(zone2.getRules());// ZoneRules[currentStandardOffset=-03:00]

        LocalTime now1 = LocalTime.now(zone1);
        LocalTime now2 = LocalTime.now(zone2);
        System.out.println(now1.isBefore(now2)); // false
        System.out.println(now1.isAfter(now2));
        long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
        long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
        System.out.println(hoursBetween); // -4
        System.out.println(minutesBetween); // -299
    }


    /**
     * LocalDate(本地日期)
     * LocalDate 表示了一个确切的日期，比如 2014-03-11。该对象值是不可变的，用起来和LocalTime基本
     * 一致。下面的例子展示了如何给Date对象加减天/月/年。另外要注意的是这些对象是不可变的，操作返
     * 回的总是一个新实例。
     */
    @Test
    public void test2(){
        LocalDate today = LocalDate.now();//获取现在的日期
        System.out.println("今天的日期: "+today);//2020-09-19
        LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
        System.out.println("明天的日期: "+tomorrow);//2020-09-20
        LocalDate yesterday = tomorrow.minusDays(2);
        System.out.println("昨天的日期: "+yesterday);//2020-09-18
        LocalDate independenceDay = LocalDate.of(2020, Month.MARCH, 12);
        DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();
        System.out.println("今天是周几:"+dayOfWeek);//TUESDAY
    }
    /**
     * 从字符串解析一个 LocalDate 类型和解析 LocalTime
     */
    @Test
    public void test3(){
        String str1 = "2014==04==12 01时06分09秒";
// 根据需要解析的日期、时间字符串定义解析所用的格式器
        DateTimeFormatter fomatter1 = DateTimeFormatter
                .ofPattern("yyyy==MM==dd HH时mm分ss秒");
        LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1);
        System.out.println(dt1); // 输出 2014-04-12T01:06:09
        String str2 = "2014$$$四月$$$13 20小时";
        DateTimeFormatter fomatter2 = DateTimeFormatter
                .ofPattern("yyy$$$MMM$$$dd HH小时");
        LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2);
        System.out.println(dt2); // 输出 2014-04-13T20:00

    }
    /**
     * 获取当前时间  并格式化日期
     *
     */
    @Test
    public void test4(){
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        // 格式化当前时间 ->string
        String format = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(now);
        System.out.println(format);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
        String format1 = dateTimeFormatter.format(now);
        System.out.println(format1);

        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("YYYY年MM月dd日 HH时mm分ss秒");
        String format2 = dateTimeFormatter1.format(now);
        System.out.println(format2);

    }
    /**
     * LocalDateTime 提供了一些能访问具体字段的方法。
     * 获取当前时间是哪一年，哪一月，周几······等
     */
    @Test
    public void test5(){
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        System.out.println(year);
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        System.out.println(dayOfWeek);
        Month month = now.getMonth();
        System.out.println(month);

        // 实际场景 传入时间字符串获取年月日
        String str1 = "2014==04==12 01时06分09秒";
        DateTimeFormatter fomatter1 = DateTimeFormatter
                .ofPattern("yyyy==MM==dd HH时mm分ss秒");
        LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1);
        int year1 = dt1.getYear();
        System.out.println(year1);

    }
    /**
     * 和java.text.NumberFormat不一样的是新版的DateTimeFormatter是不可变的，所以它是线程安全的。
     */
}
